{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模块\n",
    "* 模块是一个包含所有你定义的函数和变量的文件，其后缀名是.py。模块可以被别的程序引入，以使用该模块中的函数等功能。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 引用系统模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(sys.path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 为什么需要__init__.py \n",
    "__init__.py文件用于组织包（package）。这里首先需要明确包（package）的概念。什么是包（package）？简单来说，包是含有python模块的文件夹。一个python模块（module）为一个py文件，里面写有函数和类。包（package）是为了更好的管理模块（module）,相当于多个模块的父节点。\n",
    "\n",
    "当文件夹下有__init__.py时，表示当前文件夹是一个package，其下的多个module统一构成一个整体。这些module都可以通过同一个package引入代码中。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pycharm自定义头部模板\n",
    "* File->settings->Editor->File and Code Templates->Python Script\n",
    "\n",
    "``` python\n",
    "#!/usr/bin/env python\n",
    "# -*- coding: utf-8 -*-\n",
    "\"\"\"\n",
    "@Time    : ${DATE} ${TIME}\n",
    "@Author  : zichao.li\n",
    "@Site    : ${SITE}\n",
    "@File    : ${NAME}\n",
    "@Software: ${PRODUCT_NAME}\n",
    "\"\"\"\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    pass\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 执行自定义模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%run mod/show.py hello lets start quant trade"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%magic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 引用自定义模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mod.show\n",
    "prt=mod.show.prt\n",
    "prt(9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mod.show.prt(8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# import 语句\n",
    "* 想使用 Python 源文件，只需在另一个源文件里执行 import 语句，语法如下：\n",
    "> import module1[, module2[,... moduleN]\n",
    "\n",
    "* 当解释器遇到 import 语句，如果模块在当前的搜索路径就会被导入。\n",
    "* 一个模块只会被导入一次，不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。\n",
    "* 当我们使用import语句的时候，Python解释器是怎样找到对应的文件的呢？\n",
    "> 这就涉及到Python的搜索路径，搜索路径是由一系列目录名组成的，Python解释器就依次从这些目录中去寻找所引入的模块。\n",
    "这看起来很像环境变量，事实上，也可以通过定义环境变量的方式来确定搜索路径。\n",
    "搜索路径是在Python编译或安装的时候确定的，安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# from…import 语句\n",
    "Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中，语法如下：\n",
    "```\n",
    "from modname import name1[, name2[, ... nameN]]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mod.show import jiafa,jianfa,prt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "jiafa(1,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "jianfa(2,4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mod.show import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "function"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(jiafa)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 深入模块\n",
    "* 模块除了方法定义，还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。\n",
    "* 每个模块有各自独立的符号表，在模块内部为所有的函数当作全局符号表来使用。所以，模块的作者可以放心大胆的在模块内部使用这些全局变量，而不用担心把其他用户的全局变量搞花。\n",
    "* 从另一个方面，当你确实知道你在做什么的话，你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。\n",
    "* 模块是可以导入其他模块的。在一个模块（或者脚本，或者其他地方）的最前面使用 import 来导入一个模块，当然这只是一个惯例，而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。\n",
    "* 还有一种导入的方法，可以使用 import 直接把模块内（函数，变量的）名称导入到当前操作模块。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# \\__name\\__属性\n",
    "一个模块被另一个程序第一次引入时，其主程序将运行。如果我们想在模块被引入时，模块中的某一程序块不执行，我们可以用\\__name\\__属性来使该程序块仅在该模块自身运行时执行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello quant\n"
     ]
    }
   ],
   "source": [
    "from mod import show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello quant\n",
      "main program\n"
     ]
    }
   ],
   "source": [
    "%run mod/show.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "说明： 每个模块都有一个\\__name\\__属性，当其值是'\\__main\\__'时，表明该模块自身在运行，否则是被引入。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# dir() 函数\n",
    "内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__builtins__',\n",
       " '__cached__',\n",
       " '__doc__',\n",
       " '__file__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__spec__',\n",
       " 'jiafa',\n",
       " 'jianfa',\n",
       " 'prt',\n",
       " 'sys']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(show)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__displayhook__',\n",
       " '__doc__',\n",
       " '__excepthook__',\n",
       " '__interactivehook__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__spec__',\n",
       " '__stderr__',\n",
       " '__stdin__',\n",
       " '__stdout__',\n",
       " '_clear_type_cache',\n",
       " '_current_frames',\n",
       " '_debugmallocstats',\n",
       " '_enablelegacywindowsfsencoding',\n",
       " '_getframe',\n",
       " '_git',\n",
       " '_home',\n",
       " '_xoptions',\n",
       " 'api_version',\n",
       " 'argv',\n",
       " 'base_exec_prefix',\n",
       " 'base_prefix',\n",
       " 'builtin_module_names',\n",
       " 'byteorder',\n",
       " 'call_tracing',\n",
       " 'callstats',\n",
       " 'copyright',\n",
       " 'displayhook',\n",
       " 'dllhandle',\n",
       " 'dont_write_bytecode',\n",
       " 'exc_info',\n",
       " 'excepthook',\n",
       " 'exec_prefix',\n",
       " 'executable',\n",
       " 'exit',\n",
       " 'flags',\n",
       " 'float_info',\n",
       " 'float_repr_style',\n",
       " 'get_asyncgen_hooks',\n",
       " 'get_coroutine_wrapper',\n",
       " 'getallocatedblocks',\n",
       " 'getcheckinterval',\n",
       " 'getdefaultencoding',\n",
       " 'getfilesystemencodeerrors',\n",
       " 'getfilesystemencoding',\n",
       " 'getprofile',\n",
       " 'getrecursionlimit',\n",
       " 'getrefcount',\n",
       " 'getsizeof',\n",
       " 'getswitchinterval',\n",
       " 'gettrace',\n",
       " 'getwindowsversion',\n",
       " 'hash_info',\n",
       " 'hexversion',\n",
       " 'implementation',\n",
       " 'int_info',\n",
       " 'intern',\n",
       " 'is_finalizing',\n",
       " 'maxsize',\n",
       " 'maxunicode',\n",
       " 'meta_path',\n",
       " 'modules',\n",
       " 'path',\n",
       " 'path_hooks',\n",
       " 'path_importer_cache',\n",
       " 'platform',\n",
       " 'prefix',\n",
       " 'ps1',\n",
       " 'ps2',\n",
       " 'ps3',\n",
       " 'set_asyncgen_hooks',\n",
       " 'set_coroutine_wrapper',\n",
       " 'setcheckinterval',\n",
       " 'setprofile',\n",
       " 'setrecursionlimit',\n",
       " 'setswitchinterval',\n",
       " 'settrace',\n",
       " 'stderr',\n",
       " 'stdin',\n",
       " 'stdout',\n",
       " 'thread_info',\n",
       " 'version',\n",
       " 'version_info',\n",
       " 'warnoptions',\n",
       " 'winver']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir(sys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 包\n",
    "* 包是一种管理 Python 模块命名空间的形式，采用\"点模块名称\"。比如一个模块的名称是 A.B， 那么他表示一个包 A中的子模块 B 。就好像使用模块的时候，你不用担心不同模块之间的全局变量相互影响一样，采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。\n",
    "* 在导入一个包的时候，Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。\n",
    "* 目录只有包含一个叫做 \\__init\\__.py 的文件才会被认作是一个包。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
